<template>
	<view class="signature-page">
		<view :class="{ 'bottom': screenStatus == 'vertical', 'bottom-reset': screenStatus == 'horizontal' }">
			<!-- 竖屏 -->
			<view class="tit" v-if="screenStatus == 'vertical'">请<slot name='name'></slot>
				<rich-text v-if="prompts" :nodes="prompts"></rich-text>
				<text class="text-color-bold" v-else>{{ realName }}{{ userInfo.isJuveniles == 'Y' ? '的监护人' : '' }}</text>
				书写您的签名
			</view>
			<view class="sign-btn" v-if="screenStatus == 'vertical'">
				<view class="vertical-group">
					<view class="button buttonGray" @tap="handlerPrev">返回</view>
					<view class="button buttonGray" @tap="clear(false)">清除重写</view>
					<view class="button" @tap="finish">提交签名</view>
				</view>
			</view>
			<!--  -->

			<!-- horizontal-横屏 显示姓名 -->
			<view v-if="screenStatus == 'horizontal'" class="tit-reset">请<slot name='name'></slot>
				<rich-text v-if="prompts" :nodes="prompts"></rich-text>
				<text class="text-color-bold" v-else>{{ realName }}{{ userInfo.isJuveniles == 'Y' ? '的监护人' : '' }}</text>
				书写您的签名
			</view>

			<!-- 公共画布 -->
			<view
				:class="['b-box', { 'singName': screenStatus == 'vertical', 'singName-reset': screenStatus == 'horizontal' }]">
				<canvas class="mycanvas txr-sign" id="mycanvas" :canvas-id="'mycanvas' + random"
					@touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas>
			</view>
			<!--  -->

			<!-- 横屏 -->
			<view class="floot" v-if="screenStatus == 'horizontal'">
				<view class="tit-reset"></view>
				<view class="sign-btn_reset">
					<view class="button buttonGray" @tap="handlerPrev">返回</view>
					<view class="button buttonGray" @tap="clear(false)">清除重写</view>
					<view class="button" @tap="finish">提交签名</view>
				</view>
			</view>
			<!--  -->
		</view>
	</view>
</template>

<script>
/**
 * 签名canvas画板组件
 */
export default {
	name: 'SignCanvas',
	props: {
		realName: {
			type: String,
			default: ''
		},
		userInfo: { // 记录登陆者信息
			type: Object,
			default: function () {
				return {}
			}
		},
		bizClient: {
			type: String,
			default: ''
		},
		prompts: {
			type: String,
			default: ''
		},
		signImgPath: {
      type: [String],
      default: ''
    },
	},
	data() {
		return {
			signId: '', //签名ID
			isWeb: process.env.TARO_ENV === 'h5',
			//绘图图像
			ctx: '',
			random: Math.floor(Math.random() * 1000),
			//路径点集合
			points: [],
			allPoints: [],
			boundingClientRect: {
				left: 0,
				top: 0
			},
			screenStatus: 'vertical', //竖屏状态： vertical-竖屏  horizontal-横屏
			orientation: {
				new: 0,
				old: 0
			},
			drawFlag: true,
			timeId: null,
		}
	},
	computed: {
	},
	created() {
		this.canvasPrepare()
		this.setViewHeight()
		setTimeout(() => {
			this.canvasInit()
		}, 400)
	},
	methods: {
		canvasPrepare() {
			// uni.removeStorageSync("tempFilePath")
			let that = this
			this.orientation.old = this.orientation.new
			this.orientation.new = window.orientation
			// 旋转移动设备的时候进行横屏提示
			window.onorientationchange = () => {
				if (window.orientation == 90 || window.orientation == -90) {
					this.screenStatus = 'horizontal'
					console.log('横屏', window.orientation);
				} else {
					this.screenStatus = 'vertical'
					console.log('竖屏', window.orientation);
				}

				if (!this.drawFlag) return
				this.orientation.old = this.orientation.new
				this.orientation.new = window.orientation
				this.drawFlag = false
				uni.canvasToTempFilePath({
					canvasId: 'mycanvas' + this.random,
					success: function (res) {
						that.rotateBase64Img(res.tempFilePath, that.orientation.old - that.orientation.new, true, (updateUrl) => {
							uni.setStorageSync('tempFilePath', updateUrl) //暂存本地
							that.clear(true)
							that.setViewHeight()
							that.canvasInit()
						})
					}
				})
			}
			if (window.orientation == 90 || window.orientation == -90) {
				this.screenStatus = 'horizontal'
				console.log('横屏');
			} else {
				this.screenStatus = 'vertical'
				console.log("竖屏");
			}
		},
		setViewHeight() {
			/* 用于修复在默认浏览器中，vh计算视口高度不准确问题 */
			let windowVH = window.innerHeight / 100
			document.documentElement.style.setProperty('--vh', windowVH + 'px')
		},
		canvasInit() {
			clearTimeout(this.timeId)
			this.timeId = setTimeout(() => {
				this.setViewHeight()
				uni.createSelectorQuery().select('.mycanvas').boundingClientRect((rect) => {
					this.boundingClientRect.left = rect.left
					this.boundingClientRect.top = rect.top
					if (this.isWeb) {
						let selectName = `canvas[canvas-id="mycanvas${this.random}"]`
						const canvasIns = document.querySelector(selectName)
						canvasIns.width = rect.width
						canvasIns.height = rect.height
					}
				}).exec();
				this.createCanvas()
			}, 50)
		},
		// 创建画布
		createCanvas() {
			//创建绘图对象
			this.ctx = uni.createCanvasContext('mycanvas' + this.random, this)
			//设置画笔样式
			this.ctx.setLineWidth(5)
			// this.ctx.setStrokeStyle("#00ff00")
			this.ctx.lineCap = 'round'
			this.ctx.lineJoin = 'round'

			let that = this
			// setTimeout(function() {
			// 笔迹反显
			if(this.signImgPath) {
				this.allPoints = [{}]
			// if (uni.getStorageSync("tempFilePath")) {
				// let imgPath = uni.getStorageSync("tempFilePath")
				that.rotateBase64Img(this.signImgPath, 90, false, (updateUrl) => {
				let imgPath = updateUrl
				// 获取画布的宽度和高度
				uni.createSelectorQuery().select('.mycanvas').boundingClientRect((rect) => {
					let canvasWidth = rect.width
					let canvasHeight = rect.height

					// 创建一个临时的Image对象来获取图片的实际尺寸
					let img = new Image()
					img.src = imgPath
					img.onload = function() {
						let imgWidth = img.width
						let imgHeight = img.height

						// 计算缩放比例
						let scaleX = canvasWidth / imgWidth
						let scaleY = canvasHeight / imgHeight
						let scale = Math.min(scaleX, scaleY)

						// 计算图片在画布上绘制的位置
						let x = (canvasWidth - imgWidth * scale) / 2
						let y = (canvasHeight - imgHeight * scale) / 2

						// 绘制图片
						that.ctx.drawImage(
							imgPath,
							x,
							y,
							imgWidth * scale,
							imgHeight * scale
						);
						that.ctx.draw(true)
						that.drawFlag = true
					}
				}).exec();
				})
			}
			// }, 500);
		},
		touchmoveFun() {
			var e = event || window.event;
			e.preventDefault();
		},
		// 触摸开始，获取到起点
		touchstart(e) {
			// 防止了浏览器页面的滑动
			document.body.addEventListener('touchmove', this.touchmoveFun(), false);
			let startX = this.isWeb ? (e.changedTouches[0].clientX - this.boundingClientRect.left) : e.changedTouches[0].x
			let startY = this.isWeb ? (e.changedTouches[0].clientY - this.boundingClientRect.top) : e.changedTouches[0].y
			let startPoint = { X: startX, Y: startY }
			this.points.push(startPoint)
			this.allPoints.push({ X: startX, Y: startY, reBeginPath: true })
			// 每次触摸开始，开启新的路径
			if (this.ctx) this.ctx.beginPath()
		},
		// 触摸移动，获取到路径点
		touchmove(e) {
			let moveX = this.isWeb ? (e.changedTouches[0].clientX - this.boundingClientRect.left) : e.changedTouches[0].x
			let moveY = this.isWeb ? (e.changedTouches[0].clientY - this.boundingClientRect.top) : e.changedTouches[0].y
			let movePoint = { X: moveX, Y: moveY }
			this.points.push(movePoint) //存点
			this.allPoints.push(movePoint)
			let len = this.points.length
			if (len >= 2) {
				this.draw() //绘制路径
			}
		},
		// 触摸结束，将未绘制的点清空防止对后续路径产生干扰
		touchend() {
			document.body.removeEventListener('touchmove', this.touchmoveFun(), false);
			this.points = []
		},
		/*绘制笔迹
		* 1、为保证笔迹实时显示，必须在移动的同时绘制笔迹
		* 2、为保证笔迹连续，每次从路径集合中区两个点作为起点（moveTo）和终点(lineTo)
		* 3、将上一次的终点作为下一次绘制的起点（即清除第一个点）
		*/
		draw() {
			if (!this.ctx) return
			let point1 = this.points[0]
			let point2 = this.points[1]
			this.points.shift();
			this.ctx.moveTo(point1.X, point1.Y)
			this.ctx.lineTo(point2.X, point2.Y)
			const screenWidthPixels = window.screen.width * window.devicePixelRatio
			if (screenWidthPixels > 300 && screenWidthPixels < 5000) {
				//避免奇怪的屏幕尺寸
				this.ctx.lineWidth = this.screenStatus == 'horizontal' ? screenWidthPixels / 240 : screenWidthPixels / 120
			}
			this.ctx.stroke()
			this.ctx.draw(true)
		},
		clear(flag) {
			this.points = []
			if (!flag) this.allPoints = []
			// 清空画布
			let that = this
			uni.getSystemInfo({
				success: function (res) {
					let canvasw = res.windowWidth
					let canvash = res.windowHeight
					that.ctx.clearRect(0, 0, canvasw, canvash)
					that.ctx.draw(true)
				}
			})
		},
		handlerPrev() {
			this.$emit('signCancel')
		},
		finish() {
			if (!this.allPoints.length) {
				uni.showModal({
					title: '提示',
					content: '签名内容不能为空！',
					showCancel: false,
					confirmColor: '#D0122B'
				})
				return false
			}
			// 完成绘画并保存到本地
			let that = this
			uni.canvasToTempFilePath({
				canvasId: 'mycanvas' + this.random,
				success: function (res) {
					//这里的res.tempFilePath就是生成的签字图片
					// console.log("123",res.tempFilePath)
					that.rotateBase64Img(res.tempFilePath, -90, false, (updateUrl) => {
						// 测试
						that.$emit('signConfirm', { signId: '124', signImgPath: updateUrl })
						return
						// 测试end
						//走上传图片接口
						uni.uploadFile({
							url: window?.LOCAL_CONFIG?.image_service_api ? `${window.LOCAL_CONFIG.image_service_api}/file/obs/upload` : '/file/obs/upload',
							filePath: updateUrl,
							name: "file",
							withCredentials: true,
							formData: { bizClient: that.bizClient || window?.LOCAL_CONFIG?.head_source, bizCode: new Date().getTime(), imageType: 'sign' },
							header: {
								'X-Nf-Access-Token': uni.getStorageSync('token') || '',
								"X-Nf-Source": window?.LOCAL_CONFIG?.head_source || '',
								"X-Nf-Client-Code": window?.LOCAL_CONFIG?.client_code || '',
							},
							success: uploadFileRes => {
								console.log(uploadFileRes)
								if (uploadFileRes.statusCode != 200) {
									uni.showToast({
										icon: 'none',
										title: uploadFileRes.statusCode + ''
									})
									return
								}
								let data = JSON.parse(uploadFileRes.data)?.data
								if (data) {
									if (data.fileId) {
										that.signId = data.fileId
										that.$emit('signConfirm', { signId: that.signId, signImgPath: updateUrl, data })
									} else {
										uni.showToast({
											icon: 'none',
											title: '没有文件Id'
										})
									}
								}
							},
							fail: res => {
								uni.showToast({
									icon: 'none',
									title: '出错了'
								})
							}
						})
					})
				}
			})
		},
		// 横向签名旋转图片
		rotateBase64Img(src, edg, flag, callback) {
			if (this.screenStatus == 'horizontal' && !flag) {
				callback(src)
				return
			}

			var canvas = document.createElement("canvas");
			var ctx = canvas.getContext("2d");

			var imgW;//图片宽度
			var imgH;//图片高度
			var size;//canvas初始大小

			if (edg % 90 != 0) {
				console.error("旋转角度必须是90的倍数!");
				throw '旋转角度必须是90的倍数!';
			}
			(edg < 0) && (edg = (edg % 360) + 360)
			const quadrant = (edg / 90) % 4; //旋转象限
			const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 }; //裁剪坐标

			var image = new Image();
			image.crossOrigin = "anonymous"
			image.src = src;

			image.onload = function () {
				imgW = image.width;
				imgH = image.height;
				size = imgW > imgH ? imgW : imgH;
				canvas.width = size * 2;
				canvas.height = size * 2;
				switch (quadrant) {
					case 0:
						cutCoor.sx = size;
						cutCoor.sy = size;
						cutCoor.ex = size + imgW;
						cutCoor.ey = size + imgH;
						break;
					case 1:
						cutCoor.sx = size - imgH;
						cutCoor.sy = size;
						cutCoor.ex = size;
						cutCoor.ey = size + imgW;
						break;
					case 2:
						cutCoor.sx = size - imgW;
						cutCoor.sy = size - imgH;
						cutCoor.ex = size;
						cutCoor.ey = size;
						break;
					case 3:
						cutCoor.sx = size;
						cutCoor.sy = size - imgW;
						cutCoor.ex = size + imgH;
						cutCoor.ey = size + imgW;
						break;
				}
				ctx.translate(size, size);
				ctx.rotate(edg * Math.PI / 180);
				ctx.drawImage(image, 0, 0);
				var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
				if (quadrant % 2 == 0) {
					canvas.width = imgW;
					canvas.height = imgH;
				} else {
					canvas.width = imgH;
					canvas.height = imgW;
				}
				ctx.putImageData(imgData, 0, 0);
				callback(canvas.toDataURL())
			};
		},

		close() {
			this.clear()
		}
	}
}
</script>
<style lang="scss" scoped src="./index.scss"></style>
